/*
 * Control.hpp
 *
 *  Created on: 24-11-2010
 *      Author: Przemek
 */

#pragma once

#include "geometry/Rectangle.hpp"
#include "utils/GLColor.hpp"
#include "MouseListener.hpp"
#include "KeyListener.hpp"
#include "pch.hpp"

class ClipArea;

/*
 * GUI base class representing a self drawing control.
 */
class Control: public MouseListener, public KeyListener
{
	private:
		typedef std::vector<KeyListener*> KeyListenersVector;
		typedef std::vector<boost::shared_ptr<KeyListener> > ManagedKeyListenersVector;
		typedef std::vector<MouseListener*> MouseListenersVector;
		typedef std::vector<boost::shared_ptr<MouseListener> > ManagedMouseListenersVector;
		ManagedMouseListenersVector managedMouseListeners;
		MouseListenersVector mouseListeners;
		ManagedKeyListenersVector managedKeyListeners;
		KeyListenersVector keyListeners;
		geometry::Rectangle bounds;
		bool opaque;

	public:
		Control();

		const geometry::Rectangle& getBounds() const;
		virtual void setBounds(const geometry::Rectangle& placement);
		const Vector& getPosition() const;
		void setPosition(const Vector& point);
		const Dimension& getSize() const;
		virtual void setSize(const Dimension& size);
		void addManagedMouseListener(MouseListener* mouseListener);
		void addMouseListener(MouseListener* mouseListener);
		void addManagedKeyListener(KeyListener* keyListener);
		void addKeyListener(KeyListener* keyListener);

		virtual void mousePressed(const MouseListener::EventArguments& arguments);
		virtual void mouseEntered();
		virtual void mouseExited();
		virtual void mouseMoved(const MouseListener::EventArguments& arguments);
		virtual void mouseDragged(const MouseListener::EventArguments& arguments);
		virtual void mouseReleased(const MouseListener::EventArguments& arguments);
		virtual void keyPressed(const KeyListener::EventArguments& arguments);

		virtual bool isOpaque();
		virtual void setOpaque(bool opaque);
		virtual void draw(const ClipArea& clipArea) = 0;

		virtual ~Control();

	protected:
		void notifyMousePressed(const MouseListener::EventArguments& arguments);
		void notifyMouseEntered();
		void notifyMouseExited();
		void notifyMouseMoved(const MouseListener::EventArguments& arguments);
		void notifyMouseDragged(const MouseListener::EventArguments& arguments);
		void notifyMouseReleased(const MouseListener::EventArguments& arguments);
		void notifyKeyPressed(const KeyListener::EventArguments& arguments);

		Vector getCenteredTextLeftCornerPosition(const std::string& text) const;
		void drawControl(Control& control, const ClipArea& clipArea);
		void translateOglCoordinatesToControlCoordinates(const Control& control) const;
		MouseListener::EventArguments translateEventPointToControlPoint(
				const MouseListener::EventArguments& arguments, const Control& control) const;
};

